package com.customize.cas;

import org.apereo.cas.authentication.AuthenticationHandlerExecutionResult;
import org.apereo.cas.authentication.PreventedException;
import org.apereo.cas.authentication.UsernamePasswordCredential;
import org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.security.auth.login.AccountNotFoundException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;

/**
 * 我们在使用SSO单点登录的时候不只是验证一下用户名和密码是否一致,有时候还需要验证一些别的校验,那么这一张讲一下如何自定义验证器。
    <p>自定义验证很重要,因为我们后续的很多功能,都是基于自定义验证。 </p>
    CAS服务器的org.apereo.cas.authentication.AuthenticationManager负责基于提供的凭证信息进行用户认证。
    与Spring Security很相似，实际的认证委托给了一个或多个实现了org.apereo.cas.authentication.AuthenticationHandler接口的处理类。
    在cas的认证过程中逐个执行authenticationHandlers中配置的认证管理，直到有一个成功为止。
    CAS内置了一些AuthenticationHandler实现类，QueryDatabaseAuthenticationHandler中提供了基于jdbc的用户认证。
 * @author Leighton
 * @create 2018-11-09.
 * 自定义验证器
 *
 *
 * 如果需要实现自定义登录，只需要实现org.apereo.cas.authentication.AuthenticationHandler接口即可
 * 也可以利用已有的实现，比如创建一个继承自AbstractUsernamePasswordAuthenticationHandler来实现
 */
public class MyAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {

    private  static final Logger looger= LoggerFactory.getLogger(MyAuthenticationHandler.class);

    public MyAuthenticationHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order) {
        super(name, servicesManager, principalFactory, order);
    }

    /**
     * cas.authn.jdbc.query[0].* 和 cas.authn.jdbc.encode[0].*
     * 分别对应了：QueryDatabaseAuthenticationHandler 和 QueryAndEncodeDatabaseAuthenticationHandler
     * 其中使用test/123456用户登录QueryAndEncodeDatabaseAuthenticationHandler这个处理器执行成功了,所以就登录成功。
     */

    @Override
    protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential, String originalPassword) throws GeneralSecurityException, PreventedException {
       if ("admin".equals(credential.getUsername())){
           return createHandlerResult(
                                        credential,
                                        this.principalFactory.createPrincipal(credential.getUsername()),
                                        new ArrayList<>(0)
                                     );

       }else{
        throw new AccountNotFoundException("必须是admin用户才能登录");
       }
    }



}
